package jp.ddo.trismegistos.listener;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import jp.ddo.trismegistos.RsStatics;
import jp.ddo.trismegistos.container.ActionContainer;
import jp.ddo.trismegistos.dao.DaoManager;
import jp.ddo.trismegistos.exception.RsException;
import jp.ddo.trismegistos.service.DbInitializeService;
import jp.ddo.trismegistos.util.PropertiesFileReader;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

/**
 * Webアプリケーション起動・終了時のリスナークラス。
 * 
 * @author y_sugasawa
 * @since 2011/05/28
 */
@WebListener
public class StartupListener implements ServletContextListener {

	/** ログ */
	private static final Logger log = Logger.getLogger(StartupListener.class
			.getName());

	/**
	 * Webアプリケーション起動時処理。
	 * 
	 * @param arg0
	 *            サーブレットコンテキストイベント
	 */
	@Override
	public void contextInitialized(final ServletContextEvent arg0) {

		final ServletContext servletContext = arg0.getServletContext();

		try {
			// log4jの設定を行う。
			setLogSettingFilepath(servletContext
					.getRealPath("/WEB-INF/conf/log4j.xml"));

			// プロパティファイルからマスタ情報を取得
			final Map<String, String> propertiesData = readPropertiesFile(servletContext
					.getRealPath("/WEB-INF/conf/context.properties"));
			servletContext.setAttribute(RsStatics.MASTER, propertiesData);

			// アクションコンテナを初期化
			final String actionConfigPath = servletContext
					.getRealPath("/WEB-INF/conf/action.xml");
			ActionContainer.getInstaince().read(actionConfigPath);

			// DB接続情報を取得
			final String jdbcUriPre = propertiesData
					.get(RsStatics.JDBC_URI_PRE);
			final String jdbcUriPath = propertiesData
					.get(RsStatics.JDBC_URI_PATH);
			propertiesData.put(RsStatics.JDBC_URI,
					jdbcUriPre + servletContext.getRealPath(jdbcUriPath));

			// DaoManagerの初期化
			final DaoManager daoManager = (DaoManager) Class
					.forName(propertiesData.get(RsStatics.DAO_MANAGER_CLASS))
					.getConstructor(ServletContext.class)
					.newInstance(servletContext);
			servletContext.setAttribute(RsStatics.DAO_MANAGER, daoManager);

			// テーブルがなかったら作成する
			final DbInitializeService dbInitializeService = (DbInitializeService) Class
					.forName(
							propertiesData.get(RsStatics.DB_INIT_SERVICE_CLASS))
					.newInstance();
			dbInitializeService.initialize(servletContext);
		} catch (final Exception e) {
			throw new RsException(e);
		}
		log.info(servletContext.getContextPath().substring(1) + " is starup.");
	}

	/**
	 * Webアプリケーション終了時処理。
	 * 
	 * @param arg0
	 *            サーブレットコンテキストイベント
	 */
	@Override
	public void contextDestroyed(final ServletContextEvent arg0) {
	}

	/**
	 * log4jの設定ファイルのパスを設定する。
	 * 
	 * @param filePath
	 *            設定ファイルパス
	 */
	protected void setLogSettingFilepath(final String filePath) {
		DOMConfigurator.configure(filePath);
	}

	/**
	 * プロパティファイルよりアプリケーション固有の設定情報を取得する。
	 * 
	 * @param filePath
	 *            プロパティファイルパス
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	protected Map<String, String> readPropertiesFile(final String filePath)
			throws FileNotFoundException, IOException {
		return PropertiesFileReader.read(filePath);
	}

}
